import ctypes
import skf_api as skf_def

# 加载动态库
mydll = ctypes.CDLL('mtoken_gm3000.dll')
# 设置函数原型
skf_def.set_function_prototypes(mydll)


def main():
    """
    主函数，实现了以下主要逻辑：
    1. 不断循环尝试枚举设备、连接设备以及生成随机数的操作。
    2. 如果某个操作执行结果不符合预期（返回值不为成功标识），则跳过当前循环，继续下一次循环尝试。
    3. 每次成功执行完一轮操作后，计数器i加1，表示成功操作的次数。
    """
    # 用于存储函数调用返回结果，初始化为0
    ulRslt = skf_def.ULONG()
    # 设备句柄，初始化为指向一个空的 c_void_p 类型，这样后续才能正确传入 byref 函数
    hdev = skf_def.HANDLE()
    # 创建一个长度为32字节的缓冲区，用于存储生成的随机数
    pbRandom = ctypes.create_string_buffer(32)
    # 创建一个长度为256字节的缓冲区，用于存储设备名称
    szDevName = ctypes.create_string_buffer(256)
    # 用于记录设备名称缓冲区的长度，初始化为256字节
    ulNameLen = skf_def.ULONG(256)
    hkey = None
    bp = None
    pszdev = szDevName

    i = 0
    while True:
        # 清空设备名称缓冲区，将所有字节设置为0
        szDevName.value = b'\x00' * 256
        ulNameLen.value = 256
        # 调用SKF_EnumDev函数枚举设备，传入参数：是否只枚举当前存在的设备（1表示是），设备名称缓冲区，缓冲区长度的指针
        ulRslt.value = mydll.SKF_EnumDev(skf_def.BOOL(1), szDevName, ctypes.byref(ulNameLen))
        print(f"{i} {szDevName.value.decode()}")
        if ulRslt.value!= skf_def.SAR_OK:
            continue

        # 调用SKF_ConnectDev函数连接设备，传入参数：设备名称，设备句柄的指针
        ulRslt.value = mydll.SKF_ConnectDev(pszdev, ctypes.byref(hdev))
        if ulRslt.value!= skf_def.SAR_OK:
            continue

        # 调用SKF_GenRandom函数生成随机数，传入参数：设备句柄，随机数缓冲区，要生成的随机数长度
        ulRslt.value = mydll.SKF_GenRandom(hdev, pbRandom, 8)
        if ulRslt.value!= skf_def.SAR_OK:
            continue

        i += 1


if __name__ == "__main__":
    main()